package com.gaoding.shared.dict.provider;

import com.gaoding.commons.exception.NotFoundException;
import com.gaoding.commons.exception.ServiceException;
import com.gaoding.commons.exception.ValidateException;
import com.gaoding.grpc.common.protobuf.Common;
import com.gaoding.orm.jpa.search.BaseSearchable;
import com.gaoding.orm.jpa.search.SearchOperator;
import com.gaoding.shared.dict.common.constant.DictMessageConstant;
import com.gaoding.shared.dict.entity.DictService;
import com.gaoding.shared.dict.entity.DictTextContent;
import com.gaoding.shared.dict.enums.DictServiceErrorCode;
import com.gaoding.shared.dict.grpc.*;
import com.gaoding.shared.dict.repository.DictTextContentRepository;
import com.gaoding.shared.dict.service.DictServiceListService;
import com.gaoding.shared.dict.service.DictTextContentService;
import com.google.protobuf.BoolValue;
import com.google.protobuf.Int64Value;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 字典服务表 crud grpc接口实现
 *
 * @author mobai
 */
@GrpcService
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DictServiceListServiceGrpcImpl extends GdGrpcDictServiceListService {

    /**
     * 字典服务表 服务组件
     */
    private final DictServiceListService dictServiceListService;

    /**
     * 字典内容配置服务组件
     */
    private final DictTextContentService dictTextContentService;

    /**
     * 新增单条记录
     *
     * @param request
     * @return com.google.protobuf.BoolValue
     * @since 2021/2/1 9:45 上午
     */

    @Override
    public Int64Value create(CreateDictServiceListRequest request) {
        if (StringUtils.isBlank(request.getServiceCode())) {
            throw new ValidateException("服务编码不得为空");
        }
        if (StringUtils.isBlank(request.getServiceName())) {
            throw new ValidateException("服务名称不得为空");
        }
        long num = dictServiceListService.count(BaseSearchable.newSearchable().addSearchFilter("serviceCode", SearchOperator.eq, request.getServiceCode()));
        if (num > 0) {
            throw new ServiceException(DictServiceErrorCode.SERVICE_CODE_EXIST);
        }
        DictService saveEntity = DictService.builder().serviceCode(request.getServiceCode()).serviceName(request.getServiceName()).status(DictMessageConstant.DEFAULT_STATUS).build();
        try {
            return Int64Value.of(dictServiceListService.save(saveEntity).getId());
        } catch (Exception e) {
            log.error("新增服务记录出错，原因:{}", e.getMessage());
            throw e;
        }
    }

    /**
     * 更新单条记录
     *
     * @param request 更新参数
     * @return com.google.protobuf.BoolValue
     * @since 2021/2/1 9:49 上午
     */

    @Override
    public BoolValue update(UpdateDictServiceListRequest request) {
        DictService service = dictServiceListService.findOne(request.getId());
        if (service == null) {
            throw new ServiceException(DictServiceErrorCode.SERVICE_NOT_EXIST);
        }
        if (!service.getServiceCode().equals(request.getServiceCode())) {
            DictTextContentRepository repository = (DictTextContentRepository) dictTextContentService.getRepository();
            List<DictTextContent> textContents = repository.findAllByServiceCode(request.getServiceCode());
            if (CollectionUtils.isNotEmpty(textContents)) {
                throw new ServiceException(DictServiceErrorCode.SERVICE_IS_CONFIGURED);
            }
        }
        long num = dictServiceListService.count(BaseSearchable.newSearchable().addSearchFilter("serviceCode", SearchOperator.eq, request.getServiceCode()).addSearchFilter("id",SearchOperator.ne,service.getId()));
        if (num > 0) {
            throw new ServiceException(DictServiceErrorCode.SERVICE_CODE_EXIST);
        }
        service.setServiceCode(request.getServiceCode()).setServiceName(request.getServiceName());
        try {
            dictServiceListService.save(service);
            return BoolValue.of(true);
        } catch (Exception e) {
            log.error("更新服务记录出错,原因:{}", e.getMessage());
            throw e;
        }
    }


    /**
     * 根据id删除(逻辑删除)
     *
     * @param request id
     * @return com.google.protobuf.BoolValue
     * @since 2021/2/1 9:49 上午
     */

    @Override
    public BoolValue delete(Int64Value request) {
        try {
            dictServiceListService.delete(request.getValue());
            return BoolValue.of(true);
        } catch (EmptyResultDataAccessException ignored) {
            log.error("id为{}的服务记录已不存在", request.getValue());
            throw new NotFoundException(String.format("id为%s的服务记录已不存在", request.getValue()));
        }
    }


    /**
     * 分页查询
     *
     * @param request 查询参数
     * @return com.gaoding.shared.dict.grpc.DictServiceListReply
     * @since 2021/2/1 9:49 上午
     */

    @Override
    public DictServiceListReply list(QueryDictServiceListRequest request) {
        DictServiceListReply reply = DictServiceListReply.newBuilder().addAllData(Collections.emptyList()).build();
        BaseSearchable searchable = BaseSearchable.newSearchable();
        searchable.setPage(request.getPage().getPageNum(), request.getPage().getPageSize());
        if (StringUtils.isNotBlank(request.getServiceCode())) {
            searchable.addSearchFilter("serviceCode", SearchOperator.like, request.getServiceCode());
        }
        if (request.getId() != 0) {
            searchable.addSearchFilter("id", SearchOperator.eq, request.getId());
        }
        Common.Page queryPage = request.getPage();
        searchable.setPage(queryPage.getPageNum(), queryPage.getPageSize());
        Page<DictService> serviceListPage = dictServiceListService.findAll(searchable);
        if (!CollectionUtils.isEmpty(serviceListPage.getContent())) {
            List<DictServiceListInfo> serviceListInfos = serviceListPage.getContent().stream().map(this::transfer).collect(Collectors.toList());
            reply = DictServiceListReply.newBuilder().addAllData(serviceListInfos).build();
        }
        return reply;
    }


    /**
     * 实体转dto
     *
     * @param dictService 实体
     * @return com.gaoding.shared.dict.grpc.DictServiceListInfo
     * @since 2021/2/1 9:50 上午
     */

    private DictServiceListInfo transfer(DictService dictService) {
        if (dictService == null) {
            return null;
        }
        return DictServiceListInfo.newBuilder().setId(dictService.getId()).setServiceCode(dictService.getServiceCode())
                .setServiceName(dictService.getServiceName()).build();
    }
}
